home *** CD-ROM | disk | FTP | other *** search
/ DS-CD ROM 2 1993 August / DS CD-ROM 2.Ausgabe (August 1993).iso / programm / ds0334 / sim51_04.arj / SERIELL.A51 < prev    next >
Text File  |  1991-02-25  |  6KB  |  227 lines

  1. $noMod51        ; schaltet die beim ASM51 sonst default definierten
  2.             ; SFR-Declarations für den 8051 aus
  3.  
  4. $noList            ; folgender Teil des Source erscheint nicht im List-
  5.             ; File. Sinnvoll hier, um den langen Include-File,
  6.             ; nicht in List aufzunehmen.
  7.  
  8. $INCLUDE(a:\reg52.pdf)    ; Inhalt aus dem File wird hier eingefügt. Dort stehen
  9.             ; die SFR-Declarationen für den 8052
  10.  
  11. $list            ; obige "noList" - Direktrive wieder aufheben.
  12.  
  13.  
  14.  
  15.  
  16. ; ****** zur Assemblierung mit ASM51.EXE (von Intel) oder A51.EXE (von Keil)
  17. ;      oben stehen Assembler-Direktriven. Hier als Beispiel zum Einfügen der 
  18. ;      SFR-Deklarationen für eine 8052 CPU.
  19.  
  20.  
  21.  
  22. ; Proceduren zur seriellen Datenübertragung:
  23. ;-------------------------------------------
  24.  
  25. ; Hier wird als Beispiel mit absoluten Segmenten gearbeitet. 
  26.  
  27. ; Es sind Proceduren realisiert, die Daten vom seriellen Port empfangen
  28. ; - mit zwischenpufferung im internen RAM. Der eigentliche Empfang geht
  29. ;   per Interrupt.
  30. ; Senden soll direkt (ohne Interrupt) erfolgen. 
  31.  
  32.  
  33.  
  34. USING 0            ; Register-Bank 0 reservieren
  35.  
  36. USING 1            ; Register-Bank 1 reservieren
  37.  
  38.    ARxBufWrite    DATA 08        ; Inhalt von Register-Bank 1 auch über DATA-
  39.    RxBufWrite    SET R0        ; Adressen ansprechbar
  40.  
  41.    ARxBufRead    DATA 09
  42.    RxBufRead    SET R1
  43.  
  44.  
  45.  
  46. BSEG            ; (AT 0)  Bit-Adressen 00...07 in DATA-Byte 20h
  47.    TxEmpty:    DBIT 1
  48.  
  49.  
  50.  
  51. ISEG AT 21h
  52.    RxBuffer:    DS 30    ; Zwischenpuffer für Receive über Interrupt
  53.    RxBufTop:
  54.    stack:    DS 20    ; Platz für Stack reservieren
  55.  
  56.  
  57.  
  58.  
  59.  
  60. ;-----------------------------------------------------------------------------
  61. ; ***** hier Einsprung bei Reset
  62.  
  63. CSEG            ;( da erste CSEG-Direktrive = CSEG AT 0000)
  64.     JMP init
  65.  
  66.  
  67.  
  68.  
  69.  
  70. ;------------------------------------------------------------------------------
  71. ; **** hier steht die Interrupt-Routine für seriellen Port
  72.  
  73. CSEG AT SINT            ; SINT CODE 0023h vordefiniert in ASM51
  74.  
  75.     JNB    RI, sIntChkTx        ; wenn RI=0, dann kein receive Interr.
  76.     PUSH    PSW
  77.     MOV    PSW, #08        ; Reg-Bank 1 wählen, damit nicht PUSH
  78.     MOV    R7, A            ; nötig zum Sichern
  79.  
  80.     MOV    A, RxBufRead
  81.     CJNE    A, #RxBuffer, chkRxBufFull
  82.     MOV    A, #RxBufTop
  83. chkRxBufFull:
  84.     DEC    A            ; nun @A auf Byte vor @Read-Pointer
  85.     CJNE    A, ARxBufWrite, RxBufEintrag
  86.     CLR    REN
  87.     SJMP    RxSintRet        ; wenn Read-Pointer 1 Byte über Write-
  88.                     ; Pointer, kein Eintrag, REN löschen
  89.                     ; RI aber freigeben, da sonst wieder
  90.                     ; Interrupt.
  91. RxBufEintrag:
  92.     MOV    A, SBUF
  93.     MOV    @RxBufWrite, A            ; eintragen
  94.     INC    RxBufWrite            ; nächstes Byte im Ringbuffer
  95.     CJNE    RxBufWrite, #RxBufTop, RxSintRet
  96.     MOV    RxBufWrite, #RxBuffer        ; erstes Byte des Ringbuffes
  97.  
  98. RxSintRet:
  99.     CLR    RI
  100.     MOV    A, R7
  101.     POP    PSW
  102.  
  103.  
  104.  
  105. sIntChkTx:
  106.     JNB    TI, sIntRet        ; wenn TI=0, dann kein Transmit
  107.     SETB    TxEmpty            ; Flag setzen
  108.     CLR    TI            ; damit Interrupt-Bedingung weg
  109.  
  110. sIntRet:
  111.     RETI
  112.  
  113.  
  114.  
  115. ;------------------------------------------------------------------------------
  116. ; ***** Procedure für Empfang eines Zeichens (Austrag aus Ringbuffer RxBuffer)
  117. ;       warte, wenn noch keines empfangen wurde
  118.  
  119. getChar:
  120.     MOV    A, ARxBufRead
  121. getCharWait:                    ; warte bis Zeichen empfangen
  122.     CJNE    A, ARxBufWrite, RxAustragen
  123.     JMP    getCharWait
  124.  
  125. RxAustragen:
  126.     MOV    R0, A
  127.     MOV    A, @R0                ; Zeichen auslesen
  128.     INC    R0                ; Read-Pointer auf nächstes
  129.     CJNE    R0, #RxBufTop, getCharRet
  130.     MOV    R0, #RxBuffer            ; Ringbuffer-Anfang
  131. getCharRet:
  132.     MOV    ARxBufRead, R0            ; Pointer ablegen
  133.     SETB    REN                ; falls zuvor Buffer voll war
  134.     RET                    ; siehe Sint
  135.  
  136.  
  137.  
  138. ;------------------------------------------------------------------------------
  139. ; ***** Procedure zum Senden eines Zeichens (warte, wenn Buffer voll)
  140.  
  141. sendChar:
  142.     JNB    TxEmpty, $        ; TxEmpty Flag wird in SInt Routine
  143.     MOV    SBUF, A            ; gesetzt. TI kann nicht selbst ver-
  144.     CLR    TxEmpty            ; wendet werden, da dies einen Inter-
  145.     RET                ; rupt auslöst.
  146.  
  147.  
  148.  
  149. ;------------------------------------------------------------------------------
  150. ; **** hier Initialisierung nach Reset.
  151.  
  152. init:
  153.     CLR    A
  154.     MOV    PSW, A        ; eigentlich schon durch Hardware
  155.     MOV    TCON, A        ; aber hier zur Verdeutlichung nochmal
  156.     MOV    IE, A        ; weil wichtig und für Software-Reset
  157.     MOV    SCON, A
  158.  
  159.     MOV    SP, #(stack-1)
  160.  
  161.     MOV    TMOD, #20h    ; Timer1 als 8 Bit Timer mit Auto-Reload
  162.     MOV    TH1, #0FDh    ; Vorladewert für Timer1 - damit zählen:
  163.     MOV    TL1, TH1    ; FD, FE, FF, FD, ... (Teiler durch 3)
  164.     ORL    PCON, #80h    ; mit SMOD = 1 kein weiterer Teiler durch 2, d.h. das
  165.                 ; DPLL für seriell Port wird jeden 6ten CPU-
  166.                 ; Cyclus incrementiert. Da DPLL 16stellig,
  167.                 ; und 1 CPU-Cyclus = 1/12 Oszillator-Takt
  168.                 ; ergibt sich als Baud-Rate: 
  169.                 ; Oszillator ÷ 12 ÷ 3 ÷ 16 das sind 
  170.                 ; 19200 Baud bei 11.0592 MHz Oszillator
  171.     SETB    TR1        ; starte Timer 1
  172.     MOV    SCON, #40h    ; seriell Mode1: 8 bit UART mit Timer1 für BR
  173.     MOV    IE, #90h    ; seriellen Interrupt freigeben
  174.     SETB    TxEmpty                ; Transmit Leer
  175.     MOV    ARxBufWrite, #RxBuffer
  176.     MOV    ARxBufRead, #RxBuffer
  177.     SETB    REN                ; Receiver Enable
  178.  
  179.  
  180.  
  181.  
  182. ;----------------------------------------------------------------------------
  183. ; ***** Initialisierung fertig, nun Hauptprogramm
  184.  
  185.     MOV    DPTR, #TxString
  186.     MOV    R1, #(TxStringEnd - TxString)    ; Länge
  187. sendTxString:
  188.     CLR    A
  189.     MOVC    A, @A+DPTR
  190.     INC    DPTR
  191.     CALL    sendChar
  192.     DJNZ    R1, sendTxString
  193.  
  194. warteEingabe:
  195.     CALL    getChar
  196.     CJNE    A, #03, echoChar    ; CTRL-C = asci03
  197.  
  198.     CLR    EA            ; Interrupts sperren
  199.     MOV    DPTR, #jmpReset
  200.     PUSH    DPL
  201.     PUSH    DPH
  202.     RETI                ; Sprung zu reset über 2x RETI,
  203. jmpReset:                ; damit Interrupt-Logik zurück-
  204.     MOV    DPTR, #reset        ; gesetzt
  205.     PUSH    DPL
  206.     PUSH    DPH
  207.     RETI
  208.  
  209. echoChar:
  210.     CALL    sendChar
  211.     CJNE    A, #13, warteEingabe    ; bei Carriage Return zusätzlich
  212.     MOV    A, #10            ; Line Feed beim Echo
  213.     CALL    sendChar
  214.     JMP    warteEingabe
  215.  
  216.  
  217. TxString: DB 13,10,'**** Seriell Transmit Test mit 19200 Baud:',13,10
  218.       DB 13,10,'ab nun werden alle eingegebenen Zeichen als'
  219.       DB       ' Echo zur',129,'ckgeschrieben.'
  220.       DB 13,10,'CTRL-C f',129,'hrt zu einem Reset:',13,10
  221. TxStringEnd:
  222.  
  223. ; leider kennt der Assembler 'ü' nicht, deßhalb oben asc129 eingegben
  224. ; 10 = 0Ah = Line Feed,   13 = 0Dh = Carrige Return
  225.  
  226. END
  227.